package com.sbr.seb.rule.service;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class ServiceScanner {

	
	private String packageName;	
	
	public String getPackageName() {
		return packageName;
	}

	public void setPackageName(String packageName) {
		this.packageName = packageName;
	}

	/**
    * Attempts to list all the classes in the specified package as determined
    * by the context class loader
    * 
    * @param packageName
    *            the package name to search
    * @return a list of classes that exist within that package
    * @throws ClassNotFoundException
    *             if something went wrong
    */
   public List<Class<?>> getClassesForPackage() throws ClassNotFoundException {
       // This will hold a list of directories matching the pckgname. There may be more than one if a package is split over multiple jars/paths
       List<File> directories = new ArrayList<File>();
       try {
           ClassLoader cld = Thread.currentThread().getContextClassLoader();
           if (cld == null) {
               throw new ClassNotFoundException("Can't get class loader.");
           }
           String path = packageName.replace('.', '/');
           // Ask for all resources for the path
           Enumeration<URL> resources = cld.getResources(path);
           while (resources.hasMoreElements()) {
               directories.add(new File(URLDecoder.decode(resources.nextElement().getPath(), "UTF-8")));
           }
       } catch (NullPointerException x) {
           throw new ClassNotFoundException(packageName + " does not appear to be a valid package (Null pointer exception)");
       } catch (UnsupportedEncodingException encex) {
           throw new ClassNotFoundException(packageName + " does not appear to be a valid package (Unsupported encoding)");
       } catch (IOException ioex) {
           throw new ClassNotFoundException("IOException was thrown when trying to get all resources for " + packageName);
       }

       List<Class<?>> classes = new ArrayList<Class<?>>();
       // For every directory identified capture all the .class files
       for (File directory : directories) {
           if (directory.exists()) {
               // Get the list of the files contained in the package
               String[] files = directory.list();
               for (String file : files) {
                   // we are only interested in .class files
                   if (file.endsWith(".class")) {
                       // removes the .class extension
                       classes.add(Class.forName(packageName + '.' + file.substring(0, file.length() - 6)));
                   }
               }
           } else {
               throw new ClassNotFoundException(packageName + " (" + directory.getPath() + ") does not appear to be a valid package");
           }
       }
       return classes;
   }
}
